import Holiday from "./holiday.js";

class dateUtil {
  constructor() {

  }

  fixZero(n) {
    n = n.toString()
    return ('0' + n).slice(-2);
  }

  /**
   * 获取当前月 第一天，星期几
   * DES：这个月(month-1)的第一天 month = 实际月份-1
   */
  getFirstDay(year, month) {
    let date = new Date(year, month - 1, 1);
    var firstDay = {
      year: date.getFullYear(),
      month: date.getMonth() + 1,
      day: date.getDate(),
      week: date.getDay()
    }
    return firstDay;
  }

  /**
   * 获取当前月 最后一天，星期几
   * DES：0:代表上个月(month)的最后一天 month = 实际月份-1
   * 某月的第0天，即为某月的上个月的最后一天
   */
  getLastDay(year, month) {
    let date = new Date(year, month, 0);
    var lastDay = {
      year: date.getFullYear(),
      month: date.getMonth() + 1,
      day: date.getDate(),
      week: date.getDay()
    }
    return lastDay;
  }

  /**
   * 获取当前月 
   * 第一天，星期几
   * 最后一天，星期几
   * 共几天
   */
  dateGetMonthInfo(year, month) {
    let fromInfo = this.getFirstDay(year, month);
    let first = fromInfo.day;
    let weekOfFirst = fromInfo.week;
    let toInfo = this.getLastDay(year, month);
    let last = toInfo.day;
    let weekOfLast = toInfo.week;
    let days = toInfo.day;
    return {
      fromInfo, toInfo, first, weekOfFirst, last, weekOfLast, days
    };
  }

  /**
   * [dateFormat 格式化日期时间]
   * @param  {[datetimeString]} [dt]  [要转化的时间日期,留空代表当前时间]
   * @param  {[string]} fmt [格式 'yyyy-MM-dd hh:mm:ss' ]
   * @return {[datetimeString]}     [新时间日期]
   */
  dateFormat(fmt, dt = null) {
    var date = dt ? new Date((typeof dt) === 'string' ? dt.replace(/-/g, '/') : dt) : new Date();
    var o = {
      "M+": date.getMonth() + 1, //月份
      "d+": date.getDate(), //日
      "h+": date.getHours(), //小时
      "m+": date.getMinutes(), //分
      "s+": date.getSeconds(), //秒
      "q+": Math.floor((date.getMonth() + 3) / 3), //季度
      "S": date.getMilliseconds() //毫秒
    };
    if (/(y+)/.test(fmt))
      fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o)
      if (new RegExp("(" + k + ")").test(fmt))
        fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    // console.log('格式化后的时间为：', fmt);
    return fmt;
  }

  /**
 * [dateAdd 为指定时间日期增加 diff的 年|月|日|时|分|秒]
 * @param  {[datetimeString]} basedtime [基础时间]
 * @param  {[string]} type      [指定增加类型 year|month|day|hour|minute|second]
 * @param  {[int]} diff      [增量]
 * @return {[datetimeString]}           [newdt 新日期时间]
 */
  dateAdd(type, diff, basedtime = '') {
    var dt = basedtime ? new Date(basedtime.replace(/-/g, '/')) : new Date();
    switch (type) {
      case 'year':
        dt.setFullYear(dt.getFullYear() + diff);
        break;
      case 'month':
        dt.setMonth(dt.getMonth() + diff);
        break;
      case 'day':
        dt.setDate(dt.getDate() + diff);
        break;
      case 'hour':
        dt.setHours(dt.getHours() + diff);
        break;
      case 'minute':
        dt.setMinutes(dt.getMinutes() + diff);
        break;
      case 'second':
        dt.setSeconds(dt.getSeconds() + diff);
        break;
    }
    var newdtime = this.dateFormat('yyyy-MM-dd', dt);
    console.log('原时间:', this.dateFormat(basedtime, 'yyyy-MM-dd hh:mm:ss'), '的', type, '加上', diff, '后的新时间:', newdtime);
    return newdtime;
  }

  dateDiff(endDT, startDT) {
    endDT = endDT.indexOf('-') > 0 ? endDT.replace(/-/g, '/') : endDT;
    if (startDT) {
      startDT = startDT.indexOf('-') > 0 ? startDT.replace(/-/g, '/') : startDT;
    }

    var date1 = new Date(endDT)
    var date2 = startDT ? new Date(startDT) : new Date();

    var s1 = date1.getTime(), s2 = date2.getTime();
    var total = Math.abs((s2 - s1) / 1000);

    var day = parseInt(total / (24 * 60 * 60));//计算整数天数
    var afterDay = total - day * 24 * 60 * 60;//取得算出天数后剩余的秒数
    var hour = parseInt(afterDay / (60 * 60));//计算整数小时数
    var afterHour = total - day * 24 * 60 * 60 - hour * 60 * 60;//取得算出小时数后剩余的秒数
    var min = parseInt(afterHour / 60);//计算整数分
    var afterMin = total - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60;//取得算出分后剩余的秒数
    var sec = parseInt(afterMin);//计算整数秒
    var des = day + "天" + hour + "时" + min + "分" + sec + "秒";
    //console.log('相距时间为：',des);
    return {
      day, hour, min, sec, des
    };
  }
}

/**
 * showWeek     是否显示周栏           true：显示 false：不显示
 * showCtrl     是否显示切换月按钮      true：显示 false：不显示
 * type    点击类型              1:单选 2:范围选择
 */
export default class Calendar extends dateUtil {
  constructor(options) {
    super(options)
    let defDate = new Date();
    const defaultOptions = {
      year: defDate.getFullYear(),
      month: defDate.getMonth() + 1,
      showWeek: true,
      showCtrl: true,
      type: 'single',
      maxRange: 100
    };
    this.options = Object.assign({}, defaultOptions, options);
    console.log(defaultOptions, this.options)

    this.weeks = ['日', '一', '二', '三', '四', '五', '六'];

    this.dateRange = [];
  }

  prev(year, month) {
    return this._monthGo(year, month, -1)
  }

  next(year, month) {
    return this._monthGo(year, month, 1)
  }

  _monthGo(year, month, diff) {
    let _year = year || this.options.year;
    let _month = month || this.options.month;

    let prevMonth = this.dateAdd('month', diff, `${_year}/${_month}`)
    var newYM = this.dateFormat('yyyy-MM', prevMonth);
    var newYMZh = this.dateFormat('yyyy年MM月', prevMonth);
    const [y, m] = newYM.split("-");

    return Promise.resolve({
      date: prevMonth,
      year: y,
      month: m,
      dateDes: newYM,
      dateDesZh: newYMZh,
      monthArr: this.render({ year: y, month: m })
    })
  }

  render({ year, month, customerDates = {} }) {
    let _year = year || this.options.year;
    let _month = month || this.options.month;
    this.options.year = _year;
    this.options.month = _month;

    let dayInfoDefault = {
      day: '',//几号
      dayDes: '',//页面展示，优先显示节日名
      weekday: '',
      weekdayZh: '',
      days: '',//当月天数
      date: '',//日期Y-M-D
      dateZh: '',//日期Y年M月D日
      flag: 'PREV',//本日隶属当前月
      isHoliday: '',//节日信息对象
      isRelax: '',//本日是否休息
      isSpecialDay: false, //定义 节日或周末 为特殊日
      status: 0, //预留字段-某日的状态
      style: '', //每日格子自定义样式
    }
    let monthData = [];
    const { weekOfFirst, weekOfLast, days } = this.dateGetMonthInfo(_year, _month);
    let weekday = weekOfFirst;

    // 补齐前面的空格（上个月的数据，默认不展示）
    let preFillDays = weekOfFirst;//weekOfFirst 日在前
    // let preFillDays = weekOfFirst > 0 ? weekOfFirst - 1 : 6;//weekOfFirst-1 日在后

    let preFillInfo = Object.assign({}, dayInfoDefault, { flag: 'PREV' })
    for (let i = 0; i < preFillDays; i++) {
      monthData.push(preFillInfo)
    }

    // 当月每日信息展示
    for (let day = 1; day <= days; day++) {
      let ymd = `${_year}-${this.fixZero(_month)}-${this.fixZero(day)}`;
      let ymdZh = `${_year}年${this.fixZero(_month)}月${this.fixZero(day)}日`;
      let holiday = Holiday.getHoliday(ymd);
      let hd = holiday[0];//当日是否是法定节假日
      let rx = holiday[3];//当日是否休息
      let dayObj = {
        day: day,//几号
        dayDes: hd ? hd : day,//页面展示，优先显示节日名
        weekday: weekday,
        weekdayZh: this.weeks[weekday],
        days: days,//当月天数
        date: ymd,//日期Y-M-D
        dateZh: ymdZh,//日期Y年M月D日
        flag: 'CURRENT',//本日隶属当前月
        isHoliday: hd,//节日信息对象
        isRelax: rx,//本日是否休息
        isSpecialDay: hd || weekday === 5 || weekday === 6, //定义 节日或周末 为特殊日
        status: 0, //预留字段-某日的状态
        style: '', //每日格子自定义样式
      };

      // console.log('customerDates:', customerDates)
      // 若数据来自服务器，客户端通过组件进行传递，此处需要进行日期信息的【合并】
      if (customerDates && Object.keys(customerDates).length) {
        let prepareDay = customerDates[ymd] || {};
        dayObj = Object.assign({}, dayObj, prepareDay);
        // console.log("after assign customerDates,prepareDay:", dayObj, prepareDay)
      }

      // 自动补充周几数据
      weekday++;
      if (weekday % 7 == 0) {
        weekday = 0;
      }

      monthData.push(dayObj);
    }

    // 补齐后面的空格（下个月的数据，默认不展示）
    let endFillDays = weekOfLast > 0 ? 7 - weekOfLast : weekOfLast;
    let endFillInfo = Object.assign({}, dayInfoDefault, { flag: 'NEXT' })
    for (let j = 0; j < 6 - endFillDays; j++) {
      monthData.push(endFillInfo)
    }

    return monthData;
  }

  click(data) {
    const { type, maxRange } = this.options;
    const { date } = data;
    // 普通选择
    if (type == 'single') {
      return Promise.resolve({
        date,
        dateRange: this.dateRange
      })
    } else if (type == 'range') {
      // 范围选择
      let len = this.dateRange.length;
      let selNights = 1;
      if (len == 0 || len == 2) {
        selNights = 0;
        this.dateRange = [date];
      } else if (len == 1) {
        // 校验选择区间范围
        const { day } = this.dateDiff(date, this.dateRange[0]);
        if (day > maxRange) {
          return Promise.reject({
            error: 1,
            msg: '超出选择范围',
            nights: selNights,
            outofnights: day - maxRange
          })
        }

        //点击相同日期
        if (day == 0) {
          this.dateRange = [];
          selNights = 0;
        } else {
          // 日期排序返回
          let tmpArr = this.dateRange;
          tmpArr[1] = date;
          this.dateRange = tmpArr.sort((a, b) => {
            return new Date(a).getTime() - new Date(b).getTime()
          });
          this.dateRange = tmpArr;
          selNights = day;
        }
      }
      return Promise.resolve({
        error: 0,
        dateRange: this.dateRange,
        date: date,
        nights: selNights,
        outofnights: 0
      })
    }
  }

}